package com.filetransfer.filemanager.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import com.filetransfer.domain.FileInfoHolder;
import com.filetransfer.filemanager.util.FileUtil;



public class FileManager {

	private static FileServer server;

	private static Logger logger = Logger.getLogger(FileManager.class);

	static{
		DOMConfigurator.configure("./file-manager-log.xml");
	}



	/**
	 *
	 * @param args
	 */
	public static void main(String[] args){

		if(!validateArgs(args)){
			System.exit(1);
		}


		printBanner();
		printCommands();
		BufferedReader reader = null;
		String command = null;

		try{
			reader = new BufferedReader(new InputStreamReader(System.in));
			/*
			 * Should start the server thread.
			 * The server thread should listen to the
			 * FileInfoRequest messages and serve back the list
			 * of files from the fileholder.
			 * Also start all the serving threads. lets do the
			 * request for file on the client end.
			 */
			server.start();
			
			System.out.print("=>>");
			command = reader.readLine();
			while(!"exit".equals(command)){

				try{
					if("list-files".equals(command)){
						FileUtil.listFilesOnFileServer(server.holder);
					}else if("refresh-list".equals(command)){
						server.holder.loadFileInfoList();
						FileUtil.listFilesOnFileServer(server.holder);
					}
//					else if("start".equals(command)){
//
//					}else if("status".equals(command)){
//
//					}
					else{
						System.out.println("invalid command!");
					}
					System.out.print("=>>");
					command = reader.readLine();
				}catch(Exception e){
					logger.error("Exception in the while in the mainController:" + e.getMessage());
					e.printStackTrace();
				}
			}

			/*
			 * Reached the end of the main thread. exit command issued. kill everything and exit gracefully.
			 */
			System.exit(0);

		}catch(Exception e){
			logger.error("Exception in the main - exiting!:" + e.getMessage());
			logger.error(e.getStackTrace().toString());
			System.out.println("Faced Exception in the main method, pls check log file. exiting program!");
			System.exit(1);
		}finally{
			try{
				if(reader != null){
					reader.close();
					reader = null;
				}
			}catch(Exception e){

			}
		}


	}



	/**
	 * Validates the command line arguments and sets the argsValid boolean and
	 * other properties appropriately.
	 */
	public static boolean validateArgs(String[] args){
		boolean validArgs = false;
		int managerPort = 0;
		int[] senderPorts = null;
		String fileDir = "";
		

		/*
		 * Argument validation.
		 * usage:
		 * java com.hac.proj.main.NodeManager -managerPort <value of manager port> -group <value of node multicast grp> -nodePort <node port>
		 *
		 * e.g.,
		 * java com.hac.proj.main.NodeManager -managerPort 7007 -group 234.0.0.1 -nodePort 4455
		 */

		try{
			if(args != null && args.length == 6){

				if("-managerPort".equals(args[0])){
					managerPort = Integer.parseInt(args[1]);
					validArgs = true;
				}

				if("-senderPorts".equals(args[2])){
					String[] ports = args[3].split(",");
					senderPorts = new int[ports.length];
					for(int i=0;i<ports.length;i++){
						senderPorts[i] = Integer.parseInt(ports[i]);
					}
					validArgs = true;
				}

				if("-fileDir".equals(args[4])){
					fileDir = args[5];
					validArgs &= validArgs;
				}

				server = new FileServer(managerPort,senderPorts,fileDir);
				server.holder = new FileInfoHolder(server.fileDir,true);
				/*
				 * Start the FileServer Thread with the manager port.
				 */

			}
		}catch(Exception e){
			e.printStackTrace();
			logger.error("Exception in validateArgs!");
			logger.error(e.getStackTrace().toString());
			validArgs = false;

		}


		if(!validArgs){
			System.out.println("Usage of the File-Manager App:");
			System.out.println("=>> java com.filetransfer.filemanager.controller.FileManager -managerPort <Port on which the File manager will be listening, to be also passed on to the file downloaders> -senderPorts <Comma delimted list of ports that will be served by the file sender threads>  -fileDir <Directory where the files to be served, are stored> ");
			System.out.println("e.g.,\n=>> java com.filetransfer.filemanager.controller.FileManager -managerPort 7007 -senderPorts 7001,7002,7003 -fileDir C:\temp ");
		}


		return validArgs;
	}



	public static void printBanner(){
		System.out.println("****************************************************************");
		System.out.println("              File Service Manager - CommandLine Interface               ");
		System.out.println("****************************************************************");
	}



	/**
	 * Prints the Commands;
	 */
	public static void printCommands(){
		System.out.println("================================= Commands ========================================");
		System.out.println("list-files : lists all the files that can be served.");
		System.out.println("refresh-list : refresh the cached file list and lists the latest files that can be served.");
//		System.out.println("start : Starts the file serving threads. Number of threads depends on the number of sender ports configured.");
//		System.out.println("status : prints the status from the serving threads.");
		System.out.println("exit : Stops all the file serving threads and exits.");
		System.out.println("===================================================================================");
	}


}
